@MenuItem ("Terrain/3DObject to Terrain")static function Object2Terrain ()
{   
 // See if a valid object is selected   
 var obj = Selection.activeObject as GameObject;   
 if (obj.GetComponent(MeshFilter) == null) {
 
  EditorUtility.DisplayDialog("No mesh selected", "Please select an object with a mesh.","Cancel");   
  return; 
 
 }else if ((obj.GetComponent(MeshFilter) as MeshFilter).sharedMesh == null) {   
  EditorUtility.DisplayDialog("No mesh selected", "Please select an object with a valid mesh.", "Cancel");   
  return;     
 }   
 if (Terrain.activeTerrain == null) {   
  EditorUtility.DisplayDialog("No terrain found", "Please make sure a terrain exists.","Cancel");   
  return;   
 }  
    var terrain = Terrain.activeTerrain.terrainData;        // If there's no mesh collider, add one(and then remove it later when done)  
 var addedCollider = false;
    var addedMesh = false;
 
    var objCollider = obj.collider as MeshCollider;
   
 if (objCollider == null) {   
  objCollider = obj.AddComponent(MeshCollider);   
  addedCollider = true;   
 }else if (objCollider.sharedMesh == null) {   
  objCollider.sharedMesh = (obj.GetComponent(MeshFilter) as MeshFilter).sharedMesh;   
  addedMesh = true;
    }   
   
 Undo.RegisterUndo (terrain, "Object to Terrain");
   
 var resolutionX = terrain.heightmapWidth;
   
 var resolutionZ = terrain.heightmapHeight;
   
 var heights = terrain.GetHeights(0, 0, resolutionX, resolutionZ);   
   
 // Use bounds a bit smaller than the actual object; otherwise raycasting tends to miss at the edges
    var objectBounds = objCollider.bounds;
   
 var leftEdge = objectBounds.center.x - objectBounds.extents.x + .01;
   
 var bottomEdge = objectBounds.center.z - objectBounds.extents.z + .01;
   
 var stepX = (objectBounds.size.x - .019) / resolutionX;
   
 var stepZ = (objectBounds.size.z - .019) / resolutionZ;   
   
 // Set up raycast vars
    var y = objectBounds.center.y + objectBounds.extents.y + .01;
   
 var hit : RaycastHit;    var ray = new Ray(Vector3.zero, -Vector3.up);
   
 var rayDistance = objectBounds.size.y + .02;   
 
 var heightFactor = 1.0 / rayDistance;           
 
 // Do raycasting samples over the object to see what terrain heights should be
   
 var z = bottomEdge;
   
 for (zCount = 0; zCount < resolutionZ; zCount++) {   
  var x = leftEdge;   
  for (xCount = 0; xCount < resolutionX; xCount++) {       
   ray.origin = Vector3(x, y, z);       
   if (objCollider.Raycast(ray, hit, rayDistance)) {           
    heights[zCount, xCount] = 1.0 - (y - hit.point.y)*heightFactor;            }
   else {
    heights[zCount, xCount] = 0.0;       
   }       
   x += stepX;   
  }   
  z += stepZ;
    }   
   
 terrain.SetHeights(0, 0, heights);   
 
    if (addedMesh) {   
  objCollider.sharedMesh = null;
    }
 
    if (addedCollider) {   
  DestroyImmediate(objCollider);
    }
}